%tab2pad.m         tab2pad(fname)
%
% If you are looking at this file in your web browser, download it 
% by going to the "File --> Save As" menu option.
%
% Takes an itinerary file, produced by sfn.ScholarOne.com/itin and 
% exported in TAB-separated format, and turns it into two .mpa
% archives, suitable for importing into Memopad for Palm OS.


% Written by Carlos Brody 29-Oct-00. Freely distributable with no
% restricions whatsoever.


function [MME] = tab2pad(fname)
   
   ME = tab2entries(fname);
   ME = clean_entries(ME);
   

   % First make the abstracts file -------------
   
   if nargout > 0, MME = ME; end;
   
   Entries = cell(size(ME));
   for i=1:length(ME),
      Entries{i} = [ME(i).number ' ' ...
	     ME(i).day ' '  ME(i).time ' ' ...
	     ME(i).ampm ' ' ME(i).type ' ' ...
	     ME(i).location char([10 13])];

      Entries{i} = [Entries{i} ...
	     ME(i).title    char([10 13]) ...
	     ME(i).authors  ' ' ...
	     ME(i).affiliation char([10 13]) ...	     
	     ME(i).abstract char([10 13])];
   end;
   
   mpa_write([noextension(fname) '_abs.mpa'], Entries);
   
   
   % Now make the titles file -----------------
   
   mpa_write([noextension(fname) '_itin.mpa'], ...
       make_title_entries(ME));

   fprintf(1, ['\nFinished writing Memopad importable files:\n' ...
	  '   "%s" (itinerary) and \n' ...
	  '   "%s"  (full abstracts).\n\n'],...
       [noextension(fname) '_itin.mpa'], ...
       [noextension(fname) '_abs.mpa']);


 
   
% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   


%noextension  [r] = noextension(fname)  discard filename extension
%
% Takes a single string argument, and discards anything after (and
% including) the last '.'
%
% Does not take string matrices, but does take cell string vectors.
%


function [r] = noextension(fname)

   if isempty(fname), r = fname; return; end;
   
   if iscell(fname),
      for i=1:length(fname), fname{i} = noextension(fname{i}); end;
      r = fname;
      return;
   end;

   p = max(find(fname == '.'));
   if isempty(p),
      r = fname;
   else	
      r = fname(1:(p-1));
   end;
   
   
% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   


function [MemoEntries] = tab2entries(fname)

fp = fopen(fname, 'r'); s = fscanf(fp, '%c'); fclose(fp);

u = find(s == sprintf('\n'));
if isempty(u), MemoEntries = {}; return; end;

u = [0 u];

MemoEntries = cell(length(u)-1, 1);
for i=1:length(u)-1,
   MemoEntries{i} = s(u(i)+1:u(i+1)-1);
end;	



% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   

%clean_entries.m  [ME] = clean_entries(ME)
%
% Goes through the entries in the cell vector of strings ME, as
% obtained from tab2entries.m, and cleans them up a bit
% (e.g. removes Month and day of Month; removes AM and PM; uses
% only first three letters of day; and turns ME into a
% struct. 
%

function [nME] = clean_entries(ME)
   
   nME = struct('number', [], 'day', [], 'time', [], ...
       'ampm', [], 'conflict', [], ...
       'starttime', [], 'endtime', [], ...
       'type', [], 'title', [], 'location', [], ...
       'authors', [], 'affiliation', [], 'abstract', []);
   
   nentries = length(ME);
   nME(nentries).number = 1;
   
   i=1; while i<=nentries,
      
      u = find(ME{i} == sprintf('\t'));
      
      if isempty(u), % This is just a continued abstract
	             % from the previous entry.
	 nME(i-1).abstract = [nME(i-1).abstract ME{i}];
	 ME = ME([1:i-1  i+1:end]);      
	 nentries = nentries-1;
      
      else           % This is a real entry	 
	 nME(i).number      = padnumber(ME{i}(1 : u(1)-1));        
	 daytime            = ME{i}(u(1)+1 : u(2)-1);
	 nME(i).type        = ME{i}(u(2)+1 : u(3)-1);
	 nME(i).title       = ME{i}(u(3)+1 : u(4)-1);
	 nME(i).location    = ME{i}(u(4)+1 : u(5)-1);
	 nME(i).authors     = ME{i}(u(5)+1 : u(6)-1);
%	 nME(i).affiliation = ME{i}(u(6)+1 : u(7)-1);
	 nME(i).affiliation = ME{i}(u(6)+1 : end);
%	 nME(i).abstract    = ME{i}(u(7)+1 : end);
	 
	 [nME(i).day, nME(i).time, nME(i).ampm] = ...
	     separate_daytime(daytime);
	 
	 [nME(i).starttime, nME(i).endtime] = ...
	     military_time(nME(i).time);
	 
	 nME(i).authors = clean_authors(nME(i).authors);

	 if rem(i,10) == 0,
	    fprintf(1, 'Read entry %d ...\n', i);
	 end;
	 
	 i = i+1;  % Go on to next entry
      end;
   end;
   
   nME = nME(1:nentries);
   fprintf(1, 'Finished reading entries.\n');
   return
   
   
% -----------------

function [day, time, ampm] = separate_daytime(daytime)

   if length(daytime)<4, day = daytime; return; end;
   
   day = daytime(1:3);
   
   u = find(daytime == ',');
   if isempty(u), time = daytime(4:end); return; end
   
   time = daytime(u(end)+1:end);
   
   if     ~isempty(findstr(time, 'PM')), ampm= 'PM';
   elseif ~isempty(findstr(time, 'AM')), ampm= 'AM';
   end;
   
   time = time(find(~isspace(time) & ~isletter(time)));

   u = find(time=='-');
   if length(u) == 1  &  u>1  &  u<length(time),
      time = [time(1:u-1) '--' time(u+1:end)];
   end;
   
   return;
   
   
   
% -----------------

function [authors] = clean_authors(authors)

   u = findstr(authors, '<U>');
   keep = setdiff(1:length(authors), [u u+1 u+2]);
   authors = authors(keep);

   u = findstr(authors, '</U>');
   keep = setdiff(1:length(authors), [u u+1 u+2 u+3]);
   authors = authors(keep);

   ustart = findstr(authors, '<SUP>');
   uend   = findstr(authors, '</SUP>')+5;
   
   if length(ustart)~=length(uend), return; end;
   
   killguys = []; for i=1:length(ustart),
      killguys = [killguys ustart(i):uend(i)];
   end;
      
   keep = setdiff(1:length(authors), killguys);
   authors = authors(keep);
   
   
% ------------------

function [starttime, endtime] = military_time(time)
   
   u = find(time == '-');
   
   if length(u) < 1 | u(1) < 2 | u(end) > length(time)-1,
      starttime = 0;
      endtime = 0;
      return;
   end;
   
   starttime = time(1:u(1)-1);
   v = find(starttime == ':');
   starttime = ...
       str2num(starttime(1:v-1))*100 + str2num(starttime(v+1:end));

   endtime = time(u(end)+1:end);
   v = find(endtime == ':');
   endtime = ...
       str2num(endtime(1:v-1))*100 + str2num(endtime(v+1:end));
    
 % ----------
 
 function [num] = padnumber(num)
 
    v = find(num=='.');
    if ~isempty(v),
       numa = num(1:v-1);
       numb = num(v+1:end);
       
       if length(numa)<3, 
	  numa = ['0'*ones(1, 3-length(numa)) numa]; 
       end;	
       if length(numb)<2, 
	  numb = ['0'*ones(1, 2-length(numb)) numb]; 
       end;	 
       
       num = [numa '.' numb];   
    else
       if length(num)<3, 
	  num = ['0'*ones(1, 3-length(num)) num]; 
       end;	    
    end;	
    
    return;
    
       
% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   

%mpa_write.m   [] = mpa_write(fname, MemoEntryStrings)
%
% Writes out a .mpa (".mpa" is appended to fname if not already
% there) within a single category named "Mpa_stuff". The produced
% file is good for importing into Memopad using the Palm Desktop
% Windows PC software.
%

function [] = mpa_write(fname, MemoEntryStrings)
   
   if length(fname) <= 4, fname = [fname '.mpa']; end;
   if ~strcmp(fname(end-3:end), '.mpa'),
      fname = [fname '.mpa'];
   end;
   
   fp = fopen(fname, 'w');

   fwrite(fp, 1.2971e9 - 11232, 'uint32');
   mpa_write_cstring(fp, fname);
   mpa_write_cstring(fp, '');
   fwrite(fp, 132, 'uint32');
   fwrite(fp, 1,   'uint32');
   mpa_write_catentries(fp);

   fwrite(fp, 64, 'uint32');
   fwrite(fp, 6,  'uint32');
   fwrite(fp, 0,  'uint32');
   fwrite(fp, 1,  'uint32');
   fwrite(fp, 2,  'uint32');
   
   % FieldCount and FieldEntries:
   fwrite(fp, 6,  'uint16');
   fwrite(fp, 1,  'uint16');
   fwrite(fp, 1,  'uint16');
   fwrite(fp, 1,  'uint16');
   fwrite(fp, 5,  'uint16');
   fwrite(fp, 6,  'uint16');
   fwrite(fp, 1,  'uint16');

   % NumEntries
   fwrite(fp, length(MemoEntryStrings)*6, 'uint32');
   mpa_write_memoentries(fp, MemoEntryStrings(end:-1:1));
   fclose(fp);

   return;
   
   
% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   

%mpa_write_memoentries  [] = mpa_write_memoentries(fp,MemoStrings);
%
% Always writes CategoryID as 1; MemoString must be cell vector of 
% strings 
%

function [] = mpa_write_memoentries(fp, MemoStrings);
   % Always writes category 1
   
   for i=1:length(MemoStrings),
      
      fwrite(fp, 1, 'uint32');
      % fwrite(fp, 0, 'uint32');
      fwrite(fp, 2048+i, 'uint32');

      fwrite(fp, 1, 'uint32');
      fwrite(fp, 1, 'uint32');
      
      fwrite(fp, 1, 'uint32');
      % fwrite(fp, 2.1475e9-16353, 'uint32');
      fwrite(fp, 2048+4*i, 'uint32');
      
      fwrite(fp, 5, 'uint32');
      fwrite(fp, 0, 'uint32');
      
      mpa_write_cstring(fp, MemoStrings{i});
      
      fwrite(fp, 6, 'uint32');
      fwrite(fp, 0, 'uint32');

      fwrite(fp, 1, 'uint32');
      fwrite(fp, 1, 'uint32');
      
   end;
   

% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   



function  [] = mpa_write_cstring(fp, cstr);

   if length(cstr) < 255,
      fwrite(fp, length(cstr), 'uint8');
   else
      fwrite(fp, 255, 'uint8');
      fwrite(fp, length(cstr), 'uint16');
   end;
   
   fwrite(fp, cstr, 'uchar');

   
   
% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   



%mpa_write_catentries.m    [] = mpa_write_catentries(fp);
%
% Always writes a single category, category with ID 24 and Index
% 1, named "Mpa_stuff"
%


function [] = mpa_write_catentries(fp);
   
   fwrite(fp, 1,  'uint32');
   fwrite(fp, 24, 'uint32');
   fwrite(fp, 0,  'uint32');
   mpa_write_cstring(fp, 'Mpa_stuff');
   mpa_write_cstring(fp, 'Mpa_stuff');
   
   return;

   
% -----------------------------------------------------------   
% 
% -----------------------------------------------------------   


%make_title_entries  [TE] = make_title_entries(ME)
%
% Takes an entries struct as produced by clean_entries.m and turns 
% it into a cell vector of memopad entries with titles only
%


function [TE] = make_title_entries(ME)

   TE = {};
   currstr = '';
   
   for i=1:length(ME),
      newbit = [ME(i).number ' ' ...
	     ME(i).day ' '  ME(i).time ' ' ...
	     ME(i).ampm ' ' ME(i).type ' ' ME(i).location];

      newbit = [newbit char([10 13]) ...
	     ME(i).title    char([10 13]) ...
	     ME(i).authors  char([10 13 10 13])];
      
      if length(currstr) + length(newbit) > 4000,
	 TE = [TE ; {currstr}];
	 currstr = newbit;
      else
	 currstr = [currstr newbit];
      end;
   end;
   
   TE = [TE ; {currstr}];
      